package com.touchwisdom.modular.common.system.department;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.touchwisdom.modular.common.dao.HibernateDao;
import com.touchwisdom.modular.common.service.CommonService;
import com.touchwisdom.modular.common.system.user.TUser;
import com.touchwisdom.modular.common.system.user.TUserDao;
import com.touchwisdom.modular.util.config.Page;
import com.touchwisdom.modular.util.config.YesNoType;

/**
 * 部门信息的业务类
 * 
 * @filename DepartmentService.java
 * @date 2012-3-6 下午12:20:39
 * @author ggeagle
 * 
 */
@Service
@Transactional
public class DepartmentService extends CommonService<TDepartment, String> {

	Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private TDepartmentDao departmentDao;
	@Autowired
	private TUserDao userDao;

	@Override
	protected HibernateDao<TDepartment, String> getHibernateDao() {
		return this.departmentDao;
	}

	void getSubDepList(final Stack<TDepartment> result, String departmentId) {
		List<TDepartment> depList = this.departmentDao.findBy(TDepartment.PROPERTY_PARENT_ID, departmentId);
		result.addAll(depList);
		for (TDepartment dep : depList) {
			if (YesNoType.Y.name().equalsIgnoreCase(dep.getHasSubDep())) {
				getSubDepList(result, dep.getId());
			}
		}
	}

	/**
	 * 递归的删除部门信息，先递归的查找到全部的子部门信息，然后再逐个的进行删除
	 * 
	 * @param departmentId
	 *            父部门ID
	 */
	public void deleteByRecursion(String departmentId) {
		assert departmentId != null;
		Stack<TDepartment> result = new Stack<TDepartment>();
		TDepartment department = this.departmentDao.get(departmentId);
		result.add(department);
		if (YesNoType.Y.name().equalsIgnoreCase(department.getHasSubDep())) {
			this.getSubDepList(result, departmentId);
		}
		for (TDepartment dep : result) {
			this.departmentDao.delete(dep);
		}
	}

	/**
	 * 获取部门的子部门列表
	 * <UL>
	 * <li>如果部门ID为空，那么表示获取顶级部门信息列表</li>
	 * <li>如果部门ID不为空，那么获取该ID下的部门信息列表</li>
	 * </UL>
	 * 
	 * @param departmentId
	 * @return
	 */
	public List<TDepartment> getChildren(String departmentId) {
		List<TDepartment> depList;
		if (StringUtils.isBlank(departmentId)) {
			depList = this.departmentDao.find(Restrictions.isNull(TDepartment.PROPERTY_PARENT_ID));
		} else {
			depList = this.departmentDao.find(Restrictions.eq(TDepartment.PROPERTY_PARENT_ID, departmentId));
		}
		return depList;
	}

	/**
	 * 加载树服务
	 * 
	 * @param parentColumn
	 * @param value
	 * @return
	 */
	public TDepartment getTreeData(String parentColumn, String value) {
		// List<Department> list = departmentDao.findBy(parentColumn, value);
		TDepartment materialCategory = departmentDao.get(value);
		// materialCategory.setChildren(list);
		return materialCategory;
	}

	@Override
	public void saveEntity(TDepartment entity) {
		if (entity.getManagerId() != null) {
			TUser user = userDao.get(entity.getManagerId());
			entity.setManagerName(user.getRealName());
		}
		if (StringUtils.isNotBlank(entity.getParentId())) {
			TDepartment parent = this.departmentDao.get(entity.getParentId());
			if (YesNoType.N.name().equals(parent.getHasSubDep())) {
				parent.setHasSubDep(YesNoType.Y.name());
				super.saveEntity(parent);
			}
		}
		super.saveEntity(entity);
	}

	/**
	 * 
	 * @param id
	 * @param userId
	 * @return
	 */

	public boolean isManager(String departmentId, String userId) {
		boolean result = false;
		if (StringUtils.isNotBlank(departmentId) && StringUtils.isNotBlank(userId)) {
			result = this.departmentDao.findUnique(Restrictions.eq("managerId", userId), Restrictions.eq("id", departmentId)) != null;
		}
		return result;
	}

	/**
	 * 设置部门经理
	 * 
	 * @param department
	 */
	public void setDepManager(TDepartment department) {
		TDepartment dep = departmentDao.get(department.getId());
		dep.setManagerId(department.getManagerId());
		dep.setManagerName(department.getManagerName());
		departmentDao.save(dep);
	}

	public List<TDepartment> loadparent(String id) {
		List<TDepartment> deptList = new ArrayList<TDepartment>();
		String parentId = id;
		while (true) {
			TDepartment parentDept = this.getEntity(parentId);
			deptList.add(parentDept);
			if (StringUtils.isBlank(parentId)) {
				break;
			} else {
				parentId = parentDept.getParentId();
			}
		}
		return deptList;
	}

	/**
	 * 根据用户进行模糊查询
	 * 
	 * @param departments
	 */
	public List<TDepartment> getDepartmentByManagerName(TDepartment department) {
		Criterion criterion = null;
		if (StringUtils.isNotBlank(department.getId())) {
			criterion = Restrictions.eq("id", department.getId());
			if (StringUtils.isNotBlank(department.getManagerName())) {
				criterion = Restrictions.like("managerName", "%" + department.getManagerName() + "%");
			}
			return this.departmentDao.find(criterion);
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public Page<TUser> atDepartUsers(Page<TUser> page, String departId, String userName) {
		String hql = "from TUser user where user.departmentId =? and  user.state=? and user.userName like ?";
		Query query = departmentDao.getSession().createQuery(hql);
		query.setParameter(0, departId);
		query.setParameter(1, YesNoType.Y.name());
		query.setParameter(2, "%" + userName + "%");
		query.setFirstResult(page.getFirst() - 1);
		query.setMaxResults(page.getPageSize());
		Query countQuery = departmentDao.getSession().createQuery("select count(*) " + hql);
		countQuery.setParameter(0, departId);
		countQuery.setParameter(1, YesNoType.Y.name());
		countQuery.setParameter(2, "%" + userName + "%");
		int x = ((Long) (countQuery.list().iterator().next())).intValue();
		page.setTotalCount(x);
		page.setResult(query.list());
		return page;
	}

	@SuppressWarnings("unchecked")
	public Page<TUser> notAtDepartUsers(Page<TUser> page, String departId, String userName) {
		String hql = "from TUser user where (user.departmentId is null OR user.departmentId !=?)  and user.state=? and  user.userName like ?";
		Query query = departmentDao.getSession().createQuery(hql);
		query.setParameter(0, departId);
		query.setParameter(1, YesNoType.Y.name());
		query.setParameter(2, "%" + userName + "%");
		query.setFirstResult(page.getFirst() - 1);
		query.setMaxResults(page.getPageSize());

		Query countQuery = departmentDao.getSession().createQuery("select count(*) " + hql);
		countQuery.setParameter(0, departId);
		countQuery.setParameter(1, YesNoType.Y.name());
		countQuery.setParameter(2, "%" + userName + "%");
		int x = ((Long) (countQuery.list().iterator().next())).intValue();
		page.setTotalCount(x);
		page.setResult(query.list());
		return page;
	}

	public void deleteDepartUser(String departId) {
		logger.info("删除部门用户 departId = " + departId);
		if (departId != null) {
			String hql = "delete from t_department_user du where du.departId = ?";
			Query query = departmentDao.getSession().createQuery(hql);
			query.setParameter(0, departId);
			query.executeUpdate();
		}
	}

	public void saveDepartUser(String departId, String uid) {
		logger.info("保存部门用户 departId,uid = " + departId + "," + uid);
		String sql = "insert into t_department_t_user(id,departId,userId) values(?,?,?)";
		Query query = departmentDao.getSession().createSQLQuery(sql);
		query.setString(0, UUID.randomUUID().toString().replace("-", ""));
		query.setString(1, departId);
		query.setString(2, uid);
		query.executeUpdate();
	}

	/**
	 * 根据部门id获取该部门中的人员
	 * 
	 * @param id
	 * @return
	 */
	public List<TUser> getYUserListByDepartmentId(String id) {
		Criterion relation = Restrictions.like("departmentId", id + "%");
		Criterion relation1 = Restrictions.eq("state", YesNoType.Y.name());
		return userDao.find(relation, relation1);
	}

	/**
	 * 根据部门id和用户名获取该部门中的人员
	 * 
	 * @author wangchao
	 * @param id
	 * @return
	 */
	public List<TUser> getYUserListByDepartmentId(String id, String userName) {
		String sql = "from TUser u where u.state = ? and u.department.id= ?";
		if (userName != null) {
			sql += " and u.realName like ? ";
			return userDao.find(sql, YesNoType.Y.name(), id, "%" + userName + "%");
		} else {
			return userDao.find(sql, YesNoType.Y.name(), id);
		}
	}

	/**
	 * 根据部门id获取不是该部门中的人员
	 * 
	 * @author
	 * @author wangchao
	 * @param id
	 * @return
	 */
	public Page<TUser> getWUserListByDepartmentId(String id, String userName) {
		Page<TUser> pageuser = new Page<TUser>(10);
		pageuser.setPageNo(1);
		pageuser.setPageSize(10);
		List<TUser> setUser = this.getYUserListByDepartmentId(id);
		// 如果没有就获取所有用户
		if (setUser.size() <= 0) {
			if (userName != null) {
				Criterion relation = Restrictions.like("realName", userName);
				Criterion relation1 = Restrictions.eq("state", YesNoType.Y.name());
				pageuser.setResult(userDao.find(relation, relation1));
				return pageuser;
			}
			List<TUser> ll = userDao.find("from TUser u where u.state = ?", YesNoType.Y.name());
			pageuser.setResult(ll);
			return pageuser;
		} else { // 如果用户就排除这些用户
			StringBuffer sb = new StringBuffer();
			if (userName != null) {
				sb.append("from TUser u where u.state = ? and u.realName like ? and u.id not in (");
			} else {
				sb.append("from TUser u where u.state = ? and u.id not in (");
			}
			Iterator<TUser> uit = setUser.iterator();
			int len = setUser.size();
			int x = 0;
			while (uit.hasNext()) {
				TUser user = uit.next();
				if (x == len - 1) {
					sb.append("'");
					sb.append(user.getId());
					sb.append("')");
				} else {
					sb.append("'");
					sb.append(user.getId());
					sb.append("',");
				}

				x++;
			}
			List<TUser> wuserList = null;
			if (userName != null) {
				wuserList = this.userDao.find(sb.toString(), YesNoType.Y.name(), "%" + userName + "%");

			} else {
				wuserList = this.userDao.find(sb.toString(), YesNoType.Y.name());
			}
			pageuser.setResult(wuserList);
			return pageuser;
		}
	}

	/**
	 * 根据部门id和用户建立联系
	 * 
	 * @param departmentId
	 *            部门id
	 * @param userIds
	 *            用户ids
	 */
	public void saveUser2DepartmentId(String departmentId, String[] userIds) {
		TDepartment depart = this.departmentDao.get(departmentId);
		// 先删除之前的关联
		TDepartment d = new TDepartment();
		/*
		 * Iterator<User> userIt = Setuser.iterator();
		 * 
		 * while(userIt.hasNext()){ User us = userIt.next();
		 * us.setDepartment(d); depart.getUsers().remove(us);
		 * this.userDAO.save(us); this.departmentDao.save(depart); }
		 */
		/*
		 * for (User us : Setuser) { us.setDepartment(d);
		 * System.out.println(us.getId()); }
		 */
		this.departmentDao.save(depart);
		// 建立新的关联，一定要建立双向关联
		for (String id : userIds) {
			TUser u = this.userDao.getUserByUserId(id);
			/* u.setDepartment(depart); */
		}
		this.departmentDao.save(depart);
	}

	/**
	 * 根据管理员id查询部门信息
	 * 
	 * @author wangchao
	 * @param managerId
	 * @return
	 */
	public TDepartment queryByManagerId(String managerId) {
		return departmentDao.findUnique(Restrictions.like("managerId", managerId));
	}
}